<?php

!defined('ROOT_PATH') && exit('Forbidden');

/**
 *    订单类型基类
 *
 *    @author    Garbin
 *    @usage    none
 */
class BaseOrder extends Object
{
    function __construct($params)
    {
        $this->BaseOrder($params);
    }
    function BaseOrder($params)
    {
        if (!empty($params))
        {
            foreach ($params as $key => $value)
            {
                $this->$key = $value;
            }
        }
    }

    /**
     *    获取订单类型名称
     *
     *    @author    Garbin
     *    @return    string
     */
    function get_name()
    {
        return $this->_name;
    }

    /**
     *    获取订单详情
     *
     *    @author    Garbin
     *    @param     int $order_id
     *    @param     array $order_info
     *    @return    array
     */
    function get_order_detail($order_id, $order_info)
    {
        if (!$order_id)
        {
            return array();
        }

        /* 订单基本信息 */
        $data['order_info'] =   $order_info;

        return array('data' => $data, 'template' => 'normalorder.view.html');
    }
    /**
     *    获取该商品类型在购物流程中的表单模板及数据
     *
     *    @author    Garbin
     *    @return    array
     */
    function get_order_form()
    {
        return array();
    }

    /**
     *    处理表单提交上来后的数据，并插入订单表
     *
     *    @author    Garbin
     *    @param     array $data
     *    @return    int
     */
    function submit_order($data)
    {
        return 0;
    }

    /**
     *    响应支付通知
     *
     *    @author    Garbin
     *    @param     int    $order_id
     *    @param     array  $notify_result
     *    @return    bool
     */
    function respond_notify($order_id, $notify_result)
    {
        $model_order =& m('order');
        $where = "order_id = {$order_id}";
        $data = array('status' => $notify_result['target']);
        switch ($notify_result['target'])
        {
            case ORDER_ACCEPTED:
                $where .= ' AND status=' . ORDER_PENDING;   //只有待付款的订单才会被修改为已付款
                $data['pay_time']   =   gmtime();
            break;
            case ORDER_SHIPPED:
                $where .= ' AND status=' . ORDER_ACCEPTED;  //只有等待发货的订单才会被修改为已发货
                $data['ship_time']  =   gmtime();
            break;
            case ORDER_FINISHED:
                $where .= ' AND status=' . ORDER_SHIPPED;   //只有已发货的订单才会被自动修改为交易完成
                $data['finished_time'] = gmtime();
            break;
            case ORDER_CANCLED:                             //任何情况下都可以关闭
                /* 加回商品库存 */
                $model_order->change_stock('+', $order_id);
            break;
        }

        return $model_order->edit($where, $data);
    }

    /**
     *    获取收货人信息
     *
     *    @author    Garbin
     *    @param     int $user_id
     *    @return    array
     */
    function _get_my_address($user_id)
    {
        if (!$user_id)
        {
            return array();
        }
        $address_model =& m('address');

        return $address_model->find(array('conditions'=>'user_id=' . $user_id, 'order' => 'setdefault DESC,addr_id'));
    }
	
	 /**
     *    获取地址信息
     *
     *    @author    psmb
     *    @param     int $addr_id
     *    @return    array
     */
	function _get_address_info($addr_id)
	{
		if(!$addr_id)
		{
			return array();
		}
		$address_model =& m('address');

        return $address_model->get($addr_id);
	}

    /**
     *    获取配送方式
     *
     *    @author    Garbin
     *    @param     int $store_id
     *    @return    array
     */
    function _get_shipping_methods($store_id)
    {
        if (!$store_id)
        {
            return array();
        }
        $shipping_model =& m('shipping');

        return $shipping_model->find('enabled=1 AND store_id=' . $store_id);
    }

    /**
     *    获取支付方式
     *
     *    @author    Garbin
     *    @param     int $store_id
     *    @return    array
     */
    function _get_payments($store_id)
    {
        if (!$store_id)
        {
            return array();
        }
        $payment_model =& m('payment');

        return $payment_model->get_enabled($store_id);
    }

    /**
     *    生成订单号
     *
     *    @author    Garbin
     *    @return    string
     */
    function _gen_order_sn()
    {
        /* 选择一个随机的方案 */
        mt_srand((double) microtime() * 1000000);
        $timestamp = gmtime();
        $y = date('y', $timestamp);
        $z = date('z', $timestamp);
        $order_sn = $y . str_pad($z, 3, '0', STR_PAD_LEFT) . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);

        $model_order =& m('order');
        $orders = $model_order->find('order_sn=' . $order_sn);
        if (empty($orders))
        {
            /* 否则就使用这个订单号 */
            return $order_sn;
        }

        /* 如果有重复的，则重新生成 */
        return $this->_gen_order_sn();
    }

    /**
     *    验证收货人信息是否合法
     *
     *    @author    Garbin
     *    @param     array $consignee
     *    @return    void
     */
    function _valid_consignee_info($consignee)
    {
		if($consignee['addr_id']) {
			$consignee = array_merge($consignee, $this->_get_address_info($consignee['addr_id']));
		}
		
        if (!$consignee['consignee'])
        {
            $this->_error('consignee_empty');

            return false;
        }
        if (!$consignee['region_id'])
        {
            $this->_error('region_empty');

            return false;
        }
        if (!$consignee['address'])
        {
            $this->_error('address_empty');

            return false;
        }
        if (!$consignee['phone_tel'] && !$consignee['phone_mob'])
        {
            $this->_error('phone_required');

            return false;
        }

        if (!$consignee['delivery_type'])
        {
            $this->_error('shipping_required');

            return false;
        }

        return $consignee;
    }

    /**
     *    获取商品列表
     *
     *    @author    Garbin
     *    @param     int $order_id
     *    @return    array
     */
    function _get_goods_list($order_id)
    {
        if (!$order_id)
        {
            return array();
        }
        $ordergoods_model =& m('ordergoods');

        return $ordergoods_model->find("order_id={$order_id}");
    }

    /**
     *    获取扩展信息
     *
     *    @author    Garbin
     *    @param     int $order_id
     *    @return    array
     */
    function _get_order_extm($order_id)
    {
        if (!$order_id)
        {
            return array();
        }

        $orderextm_model =& m('orderextm');

        return $orderextm_model->get($order_id);
    }

    /**
     *    获取订单操作日志
     *
     *    @author    Garbin
     *    @param     int $order_id
     *    @return    array
     */
    function _get_order_logs($order_id)
    {
        if (!$order_id)
        {
            return array();
        }

        $model_orderlog =& m('orderlog');

        return $model_orderlog->find("order_id = {$order_id}");
    }
	
	
	/* 处理订单的支付方式 。不是货到付款就是预存款（暂时） */
	
	function _handle_payment_info(&$base_info, $post)
	{
		$payment_cod = intval($post['enable_cod']) ? 'cod' : 'deposit';//支付方式不是货到付款就是预存款
			
		$payment_mod = &m('payment');
		if (!$payment_mod->in_white_list($payment_cod))
		{
			return 0;//支付方式不在系统开启的支付白名单
		}
				
		$payment_info  = $payment_mod->get("payment_code = '".$payment_cod."' AND store_id=0");
		if (!$payment_info['enabled'])
		{
			return 0;//商家没有开启了该支付方式
		}
			
		$order_mod = &m('order');
		if($payment_cod == 'cod' && $order_mod->check_cod_enable($base_info['seller_id'],intval($post['addr_id'])) == false)
		{
			return 0;//收货地址不在货到付款的范围内
		}
		
		$base_info['payment_id'] = $payment_info['payment_id'];
		$base_info['payment_name'] = $payment_info['payment_name'];
		$base_info['payment_code'] = $payment_info['payment_code'];

		return $base_info;	
	}
	

    /**
     *    处理订单基本信息,返回有效的订单信息数组
     *
     *    @author    Garbin
     *    @param     array $goods_info
     *    @param     array $post
     *    @return    array
     */
    function _handle_order_info($goods_info, $post)
    {
        /* 默认都是待付款 */
        $order_status = ORDER_PENDING;

        /* 买家信息 */
        $visitor     =& env('visitor');
        $user_id     =  $visitor->get('user_id');
        $user_name   =  $visitor->get('user_name');

        /* 返回基本信息 */
        return array(
            'order_sn'      =>  $this->_gen_order_sn(),
            'type'          =>  $goods_info['type'],
            'extension'     =>  $this->_name,
            'seller_id'     =>  $goods_info['store_id'],
            'seller_name'   =>  addslashes($goods_info['store_name']),
            'buyer_id'      =>  $user_id,
            'buyer_name'    =>  addslashes($user_name),
            'buyer_email'   =>  $visitor->get('email'),
            'status'        =>  $order_status,
            'add_time'      =>  gmtime(),
            'goods_amount'  =>  $goods_info['amount'],
            'discount'      =>  isset($goods_info['discount']) ? $goods_info['discount'] : 0,
            'anonymous'     =>  intval($post['anonymous']),
            'postscript'    =>  trim($post['postscript']),
        );
    }

    /**
     *    处理收货人信息，返回有效的收货人信息
     *
     *    @author    Garbin
     *    @param     array $goods_info
     *    @param     array $post
     *    @return    array
     */
    function _handle_consignee_info($goods_info, $post)
    {
        /* 验证收货人信息填写是否完整 */
        $consignee_info = $this->_valid_consignee_info($post);
        if (!$consignee_info)
        {
            return false;
        }

        /* 计算配送费用 - 运费模板 */
		$shipping_name = LANG::get($post['delivery_type']);
		$shipping_fee = $this->_get_order_shippings($goods_info, intval($post['addr_id']), $post['delivery_type']);
		
        return array(
            'consignee'     =>  $consignee_info['consignee'],
            'region_id'     =>  $consignee_info['region_id'],
            'region_name'   =>  $consignee_info['region_name'],
            'address'       =>  $consignee_info['address'],
            'zipcode'       =>  $consignee_info['zipcode'],
            'phone_tel'     =>  $consignee_info['phone_tel'],
            'phone_mob'     =>  $consignee_info['phone_mob'],
            'shipping_id'   =>  0, //$post['delivery_type']
            'shipping_name' =>  addslashes($shipping_name),
            'shipping_fee'  =>  $shipping_fee,
        );
    }

    /**
     *    获取一级地区
     *
     *    @author    Garbin
     *    @param    none
     *    @return    void
     */
    function _get_regions()
    {
        $model_region =& m('region');
        $regions = $model_region->get_list(0);
        if ($regions)
        {
            $tmp  = array();
            foreach ($regions as $key => $value)
            {
                $tmp[$key] = $value['region_name'];
            }
            $regions = $tmp;
        }

        return $regions;
    }
	
	/* 获取本次订单的运费资费或获取指定地址的资费 - 运费模板 */
	function _get_order_shippings($goods_info, $consignee_addr_id = 0, $delivery_type = '')
	{
		$data = $shipping_methods = array();
		
		if(!$consignee_addr_id) 
		{
			$visitor =& env('visitor');

       	 	/* 获取我的收货地址 */
        	$data['my_address'] = $this->_get_my_address($visitor->get('user_id'));
		}
		else
		{
			/*  获取指定地址的信息 */
			$data['my_address'][$consignee_addr_id] = $this->_get_address_info($consignee_addr_id);
		}
	
		/* 根据 goods_info['items'] 找出每个商品的运费模板id */
		$goods_mod = &m('goods');
		$delivery_mod = &m('delivery_template');
		$deliverys = $base_deliverys = array();
		foreach($goods_info['items'] as $goods)
		{
			$search_goods = $goods_mod->get(array(
				'conditions'=>'goods_id='.$goods['goods_id'],
				'fields'=>'delivery_template_id'
			));
			$template_id = $search_goods['delivery_template_id'];
			
			/* 如果商品的运费模板id为0，即未设置运费模板，则获取店铺默认的运费模板（取第一个） */
			if(!$template_id || !$delivery_mod->get($template_id))
			{
				$delivery = $delivery_mod->get(array(
					'conditions'=>'store_id='.$goods_info['store_id'],
					'order'=>'template_id',
				));
				
				/* 如果店铺也没有默认的运费模板 */
				if(empty($delivery)){
					$this->_error('store_no_delivery');
					return false;
				}
							
			} else {
				$delivery = $delivery_mod->get($template_id);
			}
			
			$base_deliverys[$goods['goods_id']] = $delivery;
		}
		
		/* 根据运送目的地，获取运费情况 */
		foreach($data['my_address'] as $addr_id=>$my_address)
		{
			$city_id = $my_address['region_id']; // 此处不是 city_id 的话，可能影响也不大。
			foreach($base_deliverys as $key=>$delivery){
				$deliverys[$key] = $delivery_mod->get_city_logist($delivery,$city_id);
			}

			/* 一、如果每个商品可用的运送方式都一致，则统一计算；二、 如果有一个商品的运送方式不同，则进行组合计算 */
			/* 注：目前已经强制每个运费模板都必须设置三个运送方式，所以不存在不全等的情况。 */

			/* 1. 分别计算每个运送方式的费用：找出首费最大的那个运费方式，作为首费，并且找出作为首费的那个商品id，便于在统计运费总额时，该商品使用首费，其他商品使用续费计算 */
			$merge_info = array(
				'express' => array('start_fees'=>0,'goods_id'=>0),
				'ems'     => array('start_fees'=>0,'goods_id'=>0),
				'post'    => array('start_fees'=>0,'goods_id'=>0),
			);
			foreach($deliverys as $goods_id=>$delivery)
			{
				foreach($delivery as $template_types)
				{
					if($merge_info[$template_types['type']]['start_fees'] < $template_types['start_fees']){
						$merge_info[$template_types['type']]['start_fees'] = $template_types['start_fees'];
						$merge_info[$template_types['type']]['goods_id'] = $goods_id;
					}
				}
			}
			/* 2. 计算每个订单（店铺）的商品的总件数（包括不同规格）和每个商品的总件数（包括不同规格），以下会用到总件数来计算运费 */
			$total_quantity = 0;
			$quantity = array();
			foreach($goods_info['items'] as $goods)
			{
				$quantity[$goods['goods_id']] += $goods['quantity'];
				$total_quantity += $goods['quantity'];
			}
			/* 3. 计算总运费 */
			$logist = array();
			foreach($deliverys as $goods_id=>$delivery)
			{
				foreach($delivery as $template_types)
				{
					if($goods_id == $merge_info[$template_types['type']]['goods_id']){
						if($total_quantity > $template_types['start_standards'] && $template_types['add_standards'] > 0){
							$goods_fees = $merge_info[$template_types['type']]['start_fees'] + ($quantity[$goods_id]- $template_types['start_standards'])/$template_types['add_standards'] * $template_types['add_fees'];
							//$logist[$template_types['type']]['list_fee'][$goods_id]['logist_fee'] +=  $goods_fees;
						} else {
							$goods_fees = $merge_info[$template_types['type']]['start_fees'];
							//$logist[$template_types['type']]['list_fee'][$goods_id]['logist_fee'] +=  $goods_fees;
						}	
					}
					else
					{
						if($template_types['add_standards']>0){
							$goods_fees = $quantity[$goods_id]/$template_types['add_standards'] * $template_types['add_fees'];
						} else {
							$goods_fees = $template_types['add_fees'];
						}
						//$logist[$template_types['type']]['list_fee'][$goods_id]['logist_fee'] += $goods_fees;
					}
					$logist[$template_types['type']]['logist_fees'] += $goods_fees;
					$logist[$template_types['type']] += $template_types;
				}
			}
			$shipping_methods[$addr_id] = $logist;
		}
		
		/* 返回本次订单具体的运费资费 */
		if($consignee_addr_id && $delivery_type) {
			return $shipping_methods[$consignee_addr_id][$delivery_type]['logist_fees'];
		}
		
		/* 返回本次订单所有地址的运费资费 */
		return $shipping_methods;
	}
}

?>